﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;

namespace Silvermoon.UI
{
    public class TransitionCollection : List<Transition>
    {
    }

    public class GroupTransitions : Dictionary<int, TransitionCollection>
    {
    }

    /// <summary>
    /// Contains mutually exclusive VisualState objects that are used to go from one state to another.
    /// </summary>
    public class VisualStateGroup
    {
        private static int IndexCounter = 0;


        #region classes

        #endregion
        #region fields

        private VisualState[] states;

        #endregion
        #region ctors

        public VisualStateGroup()
            : base()
        {
        }

        public VisualStateGroup(params VisualState[] states)
            : base()
        {
            this.states = states;
        }

        #endregion
        #region props

        protected readonly int Index = IndexCounter++;

        /// <summary>
        /// Gets or sets the name of the group.
        /// </summary>
        public string Name;

        public VisualState[] States
        {
            get { return states; }
            set { states = value; }
        }


        protected static TransitionCollection GetOrCreateTransitions(IPropertyObject obj, VisualStateGroup group)
        {
            GroupTransitions gt = obj.GroupTransitions;
            if (obj.GroupTransitions == null)
            {
                gt = new GroupTransitions();
                obj.GroupTransitions = gt;
            }
            TransitionCollection col;
            if (!gt.TryGetValue(group.Index, out col))
            {
                col = new TransitionCollection();
                gt.Add(group.Index, col);
            }
            return col;
        }


        #endregion
        #region methods

        public void GoToState(IPropertyObject obj, string stateName, bool useTransition)
        {
            VisualState state = GetVisualState(stateName);
            if (state == null) throw new ArgumentOutOfRangeException("state", "State is not registered.");                 

            TransitionCollection transitions = GetTransitions(obj);
            TransitionCollection transitionsToRemove = new TransitionCollection();
            transitionsToRemove.AddRange(transitions);
            if (state.Transitions != null)
            {
                foreach (Transition transition in state.Transitions)
                {
                    transitions.Remove(transition);
                    transitions.Add(transition);
                    transition.BeginAnimation(obj, useTransition);
                    transitionsToRemove.Remove(transition);
                }
            }
            foreach (Transition transition in transitionsToRemove)
            {
                if (transition.Tracking == TrackMode.Reversible) transition.RemoveAnimation(obj, state.Duration);
                transitions.Remove(transition);
            }
            transitionsToRemove.Clear();
        }

        private TransitionCollection GetTransitions(IPropertyObject obj)
        {
            return GetOrCreateTransitions(obj, this);
        }

        public VisualState GetVisualState(string state)
        {
            if (states != null)
            {
                foreach (VisualState vs in states)
                {
                    if (vs.Name.Equals(state)) return vs;
                }
            }
            return null;
        }

        #endregion
    }
}
